package com.fanshilz.flower2025.apps.admin.sysRole.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.fanshilz.flower2025.apps.admin.satoken.AdminCurrentUser;
import com.fanshilz.flower2025.apps.admin.satoken.StpAdminUtil;
import com.fanshilz.flower2025.apps.admin.sysRole.req.SysRoleSaveOrUpdateReq;
import com.fanshilz.flower2025.apps.admin.sysRole.req.SysRoleTableReq;
import com.fanshilz.flower2025.apps.admin.sysRole.resp.SelectResp;
import com.fanshilz.flower2025.apps.admin.sysRole.resp.SysRoleTableDetailResp;
import com.fanshilz.flower2025.business.sys.sysRole.entity.SysRole;
import com.fanshilz.flower2025.business.sys.sysRole.service.ISysRoleService;
import com.fanshilz.flower2025.business.sys.sysRoleRoute.entity.SysRoleRoute;
import com.fanshilz.flower2025.business.sys.sysRoleRoute.service.ISysRoleRouteService;
import com.fanshilz.flower2025.framework.exception.CodeException;
import com.fanshilz.flower2025.framework.resp.Resp;
import com.fanshilz.flower2025.framework.resp.TableResp;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import io.github.linpeilie.Converter;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static com.fanshilz.flower2025.business.sys.sysRole.entity.table.SysRoleTableDef.SYS_ROLE;

@RestController
@RequestMapping("/admin/sysRole")
public class SysRoleController {

    @Resource
    private Converter converter;
    @Resource
    private ISysRoleService sysRoleService;
    @Resource
    private ISysRoleRouteService sysRoleRouteService;

    @PostMapping("/select")
    public Resp<List<SelectResp>> select() {
        List<SelectResp> selectResps = sysRoleService.listAs(QueryWrapper.create()
                .select(SYS_ROLE.ROLE_ID.as(SelectResp::getValue),
                        SYS_ROLE.ROLE_NAME.as(SelectResp::getLabel)), SelectResp.class);
        return Resp.success(selectResps);
    }

    @PostMapping("/remove/{roleId}")
    public Resp<Void> remove(@PathVariable Long roleId) {
        boolean b = sysRoleService.updateById(SysRole.builder()
                .roleId(roleId)
                .delFlag(true)
                .build());
        Assert.isTrue(b, CodeException::new);
        return Resp.success();
    }

    @Transactional
    @PostMapping("/saveOrUpdate")
    public Resp<Void> saveOrUpdate(@RequestBody @Valid SysRoleSaveOrUpdateReq req) {
        SysRole sr = converter.convert(req, SysRole.class);
        boolean b = sysRoleService.saveOrUpdate(sr);
        Assert.isTrue(b, CodeException::new);

        if (ObjUtil.isNotNull(req.getRoleId())) {
            AdminCurrentUser currentUser = StpAdminUtil.currentUser();
            Db.updateBySql("UPDATE sys_role_route set del_flag = true, update_user_id = ?, update_user_name = ? WHERE role_id = ?", currentUser.getUserId(), currentUser.getUserName(), req.getRoleId());
        }

        List<SysRoleRoute> list = req.getAuthorityTree().stream().distinct().<SysRoleRoute>map(a -> SysRoleRoute.builder().roleId(sr.getRoleId()).routeId(a).build()).toList();
        boolean b1 = sysRoleRouteService.saveBatch(list);
        Assert.isTrue(b1, CodeException::new);

        return Resp.success();
    }

    @PostMapping("/table")
    public Resp<TableResp<SysRoleTableDetailResp>> table(@RequestBody @Valid SysRoleTableReq req) {
        Page<SysRoleTableDetailResp> page = sysRoleService.getMapper().paginateWithRelationsAs(Page.of(req.getCurrent(), req.getPageSize(), req.getTotal()),
                QueryWrapper.create(), SysRoleTableDetailResp.class);
        return Resp.success(new TableResp<>(page.getRecords(), page.getTotalRow()));
    }

}
